Coordinator = function(db, size){
	this.size = size;
	this.sitemap = new Sitemap(db);
	var currentPage = this.sitemap.pages[0];
	var tabMgr = new TabManager(this.sitemap); //map between page id and map id
	//[page1's offset, page2's offset, page3's offset]
	// content offset, -1 = end of content
	var data = {page: currentPage.id}; //all pages
	var pointer = data;
	
	
	/*
	 * _1: data
	 * [{
			f1: 1,
			f2: 2,
			f3: 3,
			link1:{
				page: 2,
				content: [{
					f4: 4,
					f5: 5
				},{
					f4: 4,
					f5: 5
				}]
			}
		},{..}]
	 * pageId: sending page ID
	 */
	this.consume = function(_1, _np, pageId){
		//append new data to pointer
		if(!pointer.content || typeof pointer.content != 'object'){
			pointer.content = _1
		}else{
			pointer.content = pointer.content.concat(_1);
		}
		pointer.nextPage = _np;
		pointer.page = pageId;
		print("Data:");
		print(data);
		
		//find new pointer;
		pointer = _findPointer(data);
		print("Found new pointer:");
		print(pointer);
		if(pointer){
			if(pointer.page == this.sitemap.pages[0].id 
				&& this.size 
				&& data.content.length >= this.size){
				this.finish();
			}else{
				//start a new scrape
				var _ct = pointer.nextPage || pointer.content;
				if(_ct){
					if(_ct != 'client'){
						this.openTab(pointer.page, _ct);
					}else{
						//TODO
					}
				}
			}
		}else{ //end scrape
			this.finish();
		}
	}
	
	var _findPointer = function(node){
		if(!node.content){
			return;
		}
		var _t = typeof node.content;
		if(_t == 'string'){
			return node;
		}
		if(_t == 'object'){
			for (var i = 0; i < node.content.length; i++) {
				var fields = node.content[i];
				for(var k in fields){
					var v = fields[k];
					if(typeof v == 'object'){
						var _p = _findPointer(v);
						if(_p){
							return v;
						} 
					}
				}
			}
		}
		if(typeof node.nextPage == 'string'){
			return node;
		}
	}
	
	
	//open a tab
	this.openTab = function(pageId, link){
		currentPage = this.sitemap.getPage(pageId);
		chrome.tabs.create({url: link}, function(tab){
			print("====Opened Tab====pageId=" + pageId + ", tabId=" + tab.id + ", link=" + link);
			tabMgr.addTab(pageId, tab.id);
		})
	}
	
	this.readyForScrape = function(tabId){
		var pageId = tabMgr.tab2page(tabId);
		print("====Page ID====" + pageId);
		var me = this;
		chrome.tabs.sendMessage(tabId, {
			cmd: 'SCRAPE_PAGE_START',
			params:{
				db: db,
				pageId: pageId
			}
		}, function(r){
			print("====Consume====");
			print(r);
			me.consume(r.content, r.nextPage, pageId);
		});
	}
	
	var _inject = function(tabId){
		chrome.tabs.executeScript(tabId, {file: "injected/listener.js"}, function() {
			chrome.tabs.executeScript(tabId, {file: "lib/jquery/jquery-2.1.1.min.js"}, function() {
				chrome.tabs.executeScript(tabId, {file: "inspect/model.js"}, function() {
					chrome.tabs.executeScript(tabId, {file: "injected/Scraper.js"}, function() {
						chrome.tabs.executeScript(tabId, {file: "injected/worker.js"});
					});
				});
			});
		});
	}
	
	this.finish = function(){
		finish = true;
		print("====Finish====");
		print(data);
	}
	
	this.onUpdate = function(tab){
		var status = tabMgr.tabUpdate(tab);
		if(status > 0){ //old tab
			_inject(tab.id);
			if(status == 2){ //new tab
				tabMgr.addTab(currentPage.id, tab.id);
			}
		}
	}
}

